#include "serialctl.h"

SerialCtl::SerialCtl(QObject *parent) :
    QObject(parent)
{
    init();
}

SerialCtl::~SerialCtl()
{
    if (photoSensorSerialPort != NULL)
    {
        photoSensorSerialPort->cloesSeriPort();
        delete photoSensorSerialPort;
    }

       lcdSerialPotr->cloesSeriPort();
       delete lcdSerialPotr;
       displayerSPort->cloesSeriPort();
       delete displayerSPort;
}

//void SerialCtl::setPhotoToBrightK(float k)
//{
//    PhoToBrightK = k;
//}

void SerialCtl::init()
{
     m_baudRate.insert(110, BAUD110);
     m_baudRate.insert(300, BAUD300);
     m_baudRate.insert(600, BAUD600);
     m_baudRate.insert(1200, BAUD1200);
     m_baudRate.insert(2400, BAUD2400);
     m_baudRate.insert(4800, BAUD4800);
     m_baudRate.insert(9600, BAUD9600);
     m_baudRate.insert(14400, BAUD14400);
     m_baudRate.insert(19200, BAUD19200);
     m_baudRate.insert(38400, BAUD38400);
     m_baudRate.insert(56000, BAUD56000);
     m_baudRate.insert(57600, BAUD57600);
     m_baudRate.insert(115200, BAUD115200);
     m_baudRate.insert(128000, BAUD128000);

     isTisSelfTest = false;
     isCheckSLcd = false;
     m_enquiryNum = 0;
    repeatCount = 1;
    lastBrightness = -1;

    //lcd通信串口配置
    lcdSetting.defaultLv = configclass.getLcdDefaultLV();
    lcdSetting.panelInfoList = configclass.getSLCDInfoIntList();
    lcdSetting.collectPanelCount = configclass.collectSLCDCount();
    lcdSetting.isCollectPS = configclass.getIsCollectPS();

    lcdSetting.lvStruct[0] = configclass.getLv1Bright();
    lcdSetting.lvStruct[1] = configclass.getLv2Bright();
    lcdSetting.lvStruct[2] = configclass.getLv3Bright();
    lcdSetting.lvStruct[3] = configclass.getLv4Bright();
    lcdSetting.brightness = lcdSetting.lvStruct[lcdSetting.defaultLv-1].lcdBirght;

    //从配置中获取当前是否为主设备
    m_isMaterDev = configclass.IsMasterDev();

    //感光器串口初始化
    if (m_isMaterDev > 0)
    {
        photoSensorPortSettings.BaudRate = m_baudRate.value(configclass.getPhotoSensorBaud());
    }

    //感光器通信串口配置
    photoSensorPortSettings.DataBits = DATA_8;
    photoSensorPortSettings.Parity = PAR_NONE;
    photoSensorPortSettings.StopBits = STOP_1;
    photoSensorPortSettings.FlowControl = FLOW_OFF;
    photoSensorPortSettings.Timeout_Millisec = 10;

    //slcd之间的通信串口配置
    disPortSettings.BaudRate = m_baudRate.value(configclass.getSysBaud());
    disPortSettings.DataBits = DATA_8;
    disPortSettings.Parity = PAR_NONE;
    disPortSettings.StopBits = STOP_1;
    disPortSettings.FlowControl = FLOW_OFF;
    disPortSettings.Timeout_Millisec = 10;

    photoSensorSerialPort = NULL;

    //232串口ttyS,比如ttyS0  485串口ttyAP,比如ttyAP0
#ifdef _TTY_WIN_   //for win
    QString photoPortName;
    if (m_isMaterDev > 0)
    {
        photoPortName = configclass.getPhotoSensorCom();
    }

    QString disPortName = configclass.getSysCom();
#else
    QString photoPortName;
    if (m_isMaterDev > 0)
    {
        photoPortName = "/dev/" + configclass.getPhotoSensorCom();
    }

    QString disPortName = "/dev/" + configclass.getSysCom();
#endif

    if (m_isMaterDev > 0)
    {
        photoSensorSerialPort = new SerialPort(0, this);
        photoSensorSerialPort->setPort(photoPortName);
        photoSensorSerialPort->setPortSettings(photoSensorPortSettings);

        if (!photoSensorSerialPort->openSeriPort(QIODevice::ReadWrite))
        {
            logger()->error("Fail to Open photosensor serialport: %1\n", photoPortName);
            emit openPhotoSPErr();
        } else {
            logger()->info("Success to open photosensor serialport: %1\n", photoPortName);
        }

        connect(photoSensorSerialPort, SIGNAL(receSensorData(qint16)), this, SLOT(recePhotoData(qint16)));
    }

    displayerSPort = new SerialPort(3, this);
    displayerSPort->setPort(disPortName);
    displayerSPort->setPortSettings(disPortSettings);
    connect(displayerSPort, SIGNAL(receSyncCommand(SynchCommand)), this, SLOT(receSyncCommand(SynchCommand)));

    if (!displayerSPort->openSeriPort(QIODevice::ReadWrite))
    {
        logger()->error("Fail to open Displayers communication port: %1\n", disPortName);
        emit openPhotoSPErr();
    } else {
        logger()->info("Success to open Displayers communication port: %1\n", disPortName);
    }

    //LCD串口初始化
    lcdPortSettings.BaudRate = m_baudRate.value(configclass.getLcdBaud());
    lcdPortSettings.DataBits = DATA_8;
    lcdPortSettings.Parity = PAR_NONE;
    lcdPortSettings.StopBits = STOP_1;
    lcdPortSettings.FlowControl = FLOW_OFF;
    lcdPortSettings.Timeout_Millisec = 10;

#ifdef _TTY_WIN_   //for win
    QString lcdPortName = configclass.getLcdCom();
#else
    QString lcdPortName = "/dev/" + configclass.getLcdCom();
#endif

    lcdSerialPotr = new SerialPort(1, this);
    lcdSerialPotr->setPort(lcdPortName);
    lcdSerialPotr->setPortSettings(lcdPortSettings);
    lcdSerialPotr->setSendIsAscii(configclass.getSendIsAscii());
    connect(lcdSerialPotr, SIGNAL(receSensorData(qint16)), this, SLOT(recePhotoData(qint16)));

    connect(lcdSerialPotr, SIGNAL(lcdReplyBLStatus(LcdReplay)),     this, SLOT(lcdReplyBLStatus_slot(LcdReplay)));
    connect(lcdSerialPotr, SIGNAL(lcdReplyBrightness(LcdReplay)),   this, SLOT(lcdReplyBrightness_slot(LcdReplay)));
    connect(lcdSerialPotr, SIGNAL(lcdReplyReset(LcdReplay)),        this, SLOT(lcdReplyReset_slot(LcdReplay)));
    connect(lcdSerialPotr, SIGNAL(lcdReplyVideoStatu(LcdReplay)),   this, SLOT(lcdReplyVideoStatu_slot(LcdReplay)));

    connect(&m_brightCmd.timer,     SIGNAL(timeout()),  this, SLOT(timeOutSetBirght()));
    connect(&m_blStatuCmd.timer,    SIGNAL(timeout()),  this, SLOT(timeOutSetBLStatu()));
    connect(&m_queryVideoCmd.timer, SIGNAL(timeout()),  this, SLOT(timeOutQueryVideo()));
    connect(&m_reSetCmd.timer,      SIGNAL(timeout()),  this, SLOT(timeOutReSet()));

    m_brightCmd.checkCount = 0;
    m_blStatuCmd.checkCount = 0;
    m_queryVideoCmd.checkCount = 0;
    m_reSetCmd.checkCount = 0;


    if (!lcdSerialPotr->openSeriPort(QIODevice::ReadWrite))
    {
        logger()->error("Fail to open SLCD serialport %1\n", lcdPortName);
        emit openLcdSPErr();
    } else {
        lcdSerialPotr->setPanelInfoIDList(lcdSetting.panelInfoList);
        logger()->info("Success to open SLCD serialport %1\n", lcdPortName);
    }

    //LCD屏进行亮度初始化，一开始串口打开要经过一定时间才能往里面写数据不然会出现错误
    m_initTimer = new QTimer(this);
    m_initTimer->setSingleShot(true);
    connect(m_initTimer, SIGNAL(timeout()), this, SLOT(initLcdBright()));

    m_initCount = 0;
    m_initTimer->start(1 * 1000);
}


//void SerialCtl::checkSLCDStatus()
//{
//    qDebug() << "aa =============>";
//    int count = lcdSetting.panelInfoList.count();

//    for(int i = 0; i < count; i++)
//    {
//        if (lcdSetting.panelInfoList.at(i).isCollect > 0)
//            lcdSerialPotr->queryVideoStatus(lcdSetting.panelInfoList.at(i).panelID);
//    }
//    m_queryVideoCmd.cmd = 0x00;
//    m_queryVideoCmd.checkCount = 0;
//    m_queryVideoCmd.panelStatuList.clear();
//    m_queryVideoCmd.timer.start(TIMEINTERVAL);
//}

void SerialCtl::TisSelfTest()
{
    isTisSelfTest = true;
    this->queryVideoStatus(1);
}

/*******************************************
  功能：发送同步命令给从displayer
  参数：
  返回值：
  ******************************************/
void SerialCtl::sendSyncCommand(qint16 photo)
{
    SynchCommand sync;
    QDateTime dateTime;
    dateTime = QDateTime::currentDateTime();
    sync.stx = 0xFF;
    sync.enquiryNum = m_enquiryNum;
    sync.typeDev = m_isMaterDev;
    sync.year = dateTime.date().year() - 2000;
    sync.month = dateTime.date().month();
    sync.day = dateTime.date().day();
    sync.hour = dateTime.time().hour();
    sync.minute = dateTime.time().minute();
    sync.second = dateTime.time().second();
    sync.brightness = photo;
    sync.reserved = 0x00;
    sync.ext = 0xFE;
    sync.checkSum = sync.enquiryNum + sync.typeDev + sync.year + sync.month + sync.day +
            sync.hour + sync.minute + sync.second + sync.brightness;
    displayerSPort->sendSynchCommand(sync);

    m_enquiryNum++;

//    qDebug() << "sendSyncCommand===>" << sync.brightness << sync.year << sync.checkSum;
    if (m_enquiryNum > 255)
    {
        m_enquiryNum = 0;
    }
}

/*******************************************
  功能：收到感光器传来的数据，那么进行转换
  参数：
  返回值：
  ******************************************/
void SerialCtl::recePhotoData(const qint16 photo)
{
    //只有主设备才能向从设备发送同步信息，不然会出现循环发送数据的错误
    if (m_isMaterDev)
        this->sendSyncCommand(photo);


    if (lcdSetting.isCollectPS <= 0)
    {
        emit sendSensorData(photo);
        return;
    }

    //环境亮度转化为lcd屏亮度
    qint16 brightness = -1;
    for(int i = 0; i < 4; i++)
    {
        if (photo >= lcdSetting.lvStruct[i].envirStart && photo <= lcdSetting.lvStruct[i].envirEnd)
        {
            brightness = lcdSetting.lvStruct[i].lcdBirght;
        }
    }

    if (brightness == -1)
    {
        if (photo < lcdSetting.lvStruct[0].envirStart)
        {
            brightness = lcdSetting.lvStruct[0].lcdBirght;
        } else if (photo > lcdSetting.lvStruct[3].envirEnd){
            brightness = lcdSetting.lvStruct[3].lcdBirght;
        }
    }

    if (brightness > 31)
    {
        brightness = 31;
    } else if (brightness < 0)
    {
        brightness = 0;
    }

    //把收到的环境亮度转换成的SLCD亮度和最近一次SLCD亮度进行对比,如果相同，那么不进行设置
    //如果不同那么得持续2次亮度不同才进行slcd亮度设置,防止SLCD亮度反复变化
    if (brightness != lastBrightness)
    {
//        qDebug() << "photo" << lastBrightness << photo << repeatCount;
        if (repeatCount == 0)
        {
            repeatCount++;
            emit sendSensorData(photo);
            return;
        } else {
            repeatCount = 0;
            lastBrightness = brightness;
        }
    } else {
        repeatCount = 0;
        emit sendSensorData(photo);
        return;
    }

    if (g_stDebugConfig.isDebugSerialPort)
    {
        qDebug() << "recePhotoData, brightness:" << brightness;
    }

    lcdSetting.brightness = brightness;

    //开发lcd屏亮度设置
    if (lcdSerialPotr->isOpen())
    {
        lcdSerialPotr->bcastCtlbrightness(brightness);
    }
    emit sendLcdSetting(lcdSetting);
    emit sendSensorData(photo);
}


/*******************************************
  功能：检测lcd屏状态，是否正常
  参数：
  返回值：
  ******************************************/
void SerialCtl::checkLcdStatus()
{
    this->queryVideoStatus(1);
}

/*******************************************
  功能：维护终端发出想要得到lcd屏的设置，
        将lcd屏的设置发送给它
  参数：
  返回值：
  ******************************************/
void SerialCtl::checkLcdSetting()
{
    emit sendLcdSetting(lcdSetting);
}


/*******************************************
  功能：背景亮度操作
  参数：
  返回值：
  ******************************************/
void SerialCtl::changeLcdBright(const qint16 brightness, const QList<quint16> &panelIDList)
{
    m_brightCmd.timer.stop();
    m_brightCmd.panelIDList = panelIDList;
    m_brightCmd.panelStatuList.clear();
    m_brightCmd.checkCount = 0;

    lcdSetting.brightness = brightness;

    if (g_stDebugConfig.isDebugSerialPort)
    {
        qDebug() << "<<<<<<<<<<< changeLcdBright >>>>>>>>>>>>>>>" << panelIDList;
    }

    //如果是对所有的屏进行亮度设置，那么进行广播设置，如果不是，则进行单个设置
    if (m_brightCmd.panelIDList.count() == lcdSetting.panelInfoList.count())
    {
        lcdSerialPotr->bcastCtlbrightness(brightness);
        if (g_stDebugConfig.isDebugSerialPort)
        {
            qDebug() << "changeLcdBright, bcastCtlBLStatu";
        }
        for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
        {
            lcdSetting.panelInfoList[i].isCollect = 1;
        }
    } else {
        for(int i = 0; i < m_brightCmd.panelIDList.count(); i++)
        {
            for(int j = 0; j < lcdSetting.panelInfoList.count(); j++)
            {
                if (lcdSetting.panelInfoList.at(j).panelID == m_brightCmd.panelIDList.at(i))
                {
                    lcdSetting.panelInfoList[j].isCollect = 1;
                    lcdSerialPotr->ctlBrightness(m_brightCmd.panelIDList.at(i), brightness);

                    usleep(SEND_SERIALCMD_TIMEINTERVAL);
                    if (g_stDebugConfig.isDebugSerialPort)
                    {
                        qDebug() << "changeLcdBright, panelID:" << m_brightCmd.panelIDList.at(i);
                    }
                    break;
                }
            }
        }
    }

    m_brightCmd.cmd = 0xFE;
    m_brightCmd.timer.start(TIMEINTERVAL);

    emit sendSetLcdSettingStatus(1);
}


/*******************************************
  功能：改变背景灯亮度等级,此操作为维护终端发起
  参数：
  返回值：
  ******************************************/
void SerialCtl::receChangeBriLv(const LcdSettingStruct& lcdSettings)
{
//    qDebug() << "=========== receChangeBriLv ===================";

    lcdSetting.lvStruct[0] = lcdSettings.lvStruct[0];
    lcdSetting.lvStruct[1] = lcdSettings.lvStruct[1];
    lcdSetting.lvStruct[2] = lcdSettings.lvStruct[2];
    lcdSetting.lvStruct[3] = lcdSettings.lvStruct[3];
}

/*******************************************
  功能：改变背景灯状态，即开关背景灯
  参数：
  返回值：
  ******************************************/
void SerialCtl::lcdBackLightCtl(const qint8 cmd, const QList<quint16> &panelIDList)
{
//    qDebug() << "============ lcdBackLightCtl ==================" << panelIDList.count();

    m_blStatuCmd.timer.stop();
    m_blStatuCmd.panelIDList = panelIDList;
    m_blStatuCmd.panelStatuList.clear();
    m_blStatuCmd.checkCount = 0;

    if (cmd > 0)
    {
        lcdSetting.backLightStatus = 0x31;      //light on
    } else {
        lcdSetting.backLightStatus = 0x30;      //light off
    }

    //如果是对所有的屏进行设置，那么进行广播设置，如果不是，则进行单个设置
    if (m_blStatuCmd.panelIDList.count() == lcdSetting.panelInfoList.count())
    {
        lcdSerialPotr->bcastCtlBLStatu(lcdSetting.backLightStatus);
        if (g_stDebugConfig.isDebugSerialPort)
        {
            qDebug() << "lcdBackLightCtl, bcastCtlBLStatu";
        }
        for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
        {
            lcdSetting.panelInfoList[i].isCollect = 1;
        }
    } else {
        for(int i = 0; i < m_blStatuCmd.panelIDList.count(); i++)
        {
            for(int j = 0; j < lcdSetting.panelInfoList.count(); j++)
            {
                if (lcdSetting.panelInfoList.at(j).panelID == m_blStatuCmd.panelIDList.at(i))
                {
                    lcdSetting.panelInfoList[j].isCollect = 1;
                    lcdSerialPotr->ctlBLStatu(m_blStatuCmd.panelIDList.at(i), lcdSetting.backLightStatus);
                    usleep(SEND_SERIALCMD_TIMEINTERVAL);
                    if (g_stDebugConfig.isDebugSerialPort)
                    {
                        qDebug() << "lcdBackLightCtl, panelID:" << m_blStatuCmd.panelIDList.at(i);
                    }
                    break;
                }
            }
        }
    }

    m_blStatuCmd.timer.start(TIMEINTERVAL);
}

/*******************************************
  功能：查询LCD屏状态，此命令没有广播命令
  参数：
  返回值：
  ******************************************/
void SerialCtl::queryVideoStatus(const qint8 cmd)
{
    if (lcdSetting.collectPanelCount > 0)
    {
        m_queryVideoCmd.timer.stop();
        m_queryVideoCmd.panelIDList.clear();
        m_queryVideoCmd.panelStatuList.clear();
        m_queryVideoCmd.cmd = 0x00;
        m_queryVideoCmd.checkCount = 0;

        for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
        {
            m_queryVideoCmd.panelIDList.append(lcdSetting.panelInfoList.at(i).panelID);
            lcdSerialPotr->queryVideoStatus(lcdSetting.panelInfoList.at(i).panelID);
            if (g_stDebugConfig.isDebugSerialPort)
            {
                qDebug() << "queryVideoStatus" << "panelID:" << lcdSetting.panelInfoList.at(i).panelID;
            }
//            usleep(1000*1000);
            usleep(SEND_SERIALCMD_TIMEINTERVAL);
        }

        m_queryVideoCmd.timer.start(TIMEINTERVAL);
        isCheckSLcd = true;
    }
}


/*******************************************
  功能：收到lcd屏的亮度设置回复
  参数：
  返回值：
  ******************************************/
void SerialCtl::lcdReplyBrightness_slot(const LcdReplay &lcdReply)
{

//    qDebug() << "<<<<<<<<<<<<<<<<<<<<<< lcdReplyBrightness_slot >>>>>>>>>>>>>>>>>>>>>>>" << lcdReply.brightness;
    LCDSTATUS lcdStatus;
    lcdStatus.panelID = lcdReply.panelID;
    lcdStatus.brightness = lcdReply.brightness;

    if (lcdReply.brightness != lcdSetting.brightness)
    {
        lcdSerialPotr->ctlBrightness(lcdReply.panelID, lcdSetting.brightness);
    }


    for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
    {
        int j = 0;
        for(; j < m_brightCmd.panelStatuList.count(); j++)
        {
            if (m_brightCmd.panelStatuList.at(j).panelID == lcdReply.panelID)
            {
                break;
            }
        }

        if (j >= m_brightCmd.panelStatuList.count())
        {
            m_brightCmd.panelStatuList.append(lcdStatus);
        } else {
            m_brightCmd.panelStatuList.replace(j, lcdStatus);
        }
        break;
    }
}

/*******************************************
  功能：收到lcd屏的背景灯设置回复
  参数：
  返回值：
  ******************************************/
void SerialCtl::lcdReplyBLStatus_slot(const LcdReplay &lcdReply)
{
    if (g_stDebugConfig.isDebugSerialPort)
    {
        qDebug() << ".........lcdReplyBLStatus_slot.......>" << lcdReply.blStatus;
    }
    LCDSTATUS lcdStatus;
    lcdStatus.panelID = lcdReply.panelID;
    lcdStatus.blStatus = lcdReply.blStatus;

    if (lcdStatus.blStatus == 0)
    {
        lcdStatus.blStatus = LCD_BACKLIGHT_OFF;
    } else {
        lcdStatus.blStatus = LCD_BACKLIGHT_ON;
    }

    if (lcdSetting.backLightStatus != lcdReply.blStatus)
    {
        lcdSerialPotr->ctlBLStatu(lcdReply.panelID, lcdSetting.backLightStatus);
    }
    for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
    {

        int j = 0;
        for(; j < m_blStatuCmd.panelStatuList.count(); j++)
        {
            if (m_blStatuCmd.panelStatuList.at(j).panelID == lcdReply.panelID)
            {
                break;
            }
        }

        if (j >= m_blStatuCmd.panelStatuList.count())
        {
            m_blStatuCmd.panelStatuList.append(lcdStatus);
        } else {
            m_blStatuCmd.panelStatuList.replace(j, lcdStatus);
        }
        break;
    }
}

/*******************************************
  功能：收到lcd屏的设置默认状态回复
  参数：
  返回值：
  ******************************************/
void SerialCtl::lcdReplyReset_slot(const LcdReplay &lcdReply)
{
//    qDebug() << "==================<<<lcdReplyReset_slot>>> =======================";

    LCDSTATUS lcdStatus;
    lcdStatus.panelID = lcdReply.panelID;
    lcdStatus.brightness = lcdReply.brightness;

    for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
    {
        int j = 0;
        for(; j < m_reSetCmd.panelStatuList.count(); j++)
        {
            if (m_reSetCmd.panelStatuList.at(j).panelID == lcdReply.panelID)
            {
                break;
            }
        }

        if (j >= m_reSetCmd.panelStatuList.count())
        {
            m_reSetCmd.panelStatuList.append(lcdStatus);
        } else {
            m_reSetCmd.panelStatuList.replace(j, lcdStatus);
        }
        break;
    }
//    m_blStatuCmd.panelStatuList.append(lcdStatus);
    lcdSetting.brightness = lcdReply.brightness;
}

/*******************************************
  功能：收到lcd屏的状态回复
  参数：
  返回值：
  ******************************************/
void SerialCtl::lcdReplyVideoStatu_slot(const LcdReplay &lcdReply)
{
    //30,30,30,30 No Signal
    //46,31,30,30 Presence of DVI 1 input Signal
    //46,32,30,30 Presence of DVI 2 input Signal

    LCDSTATUS lcdStatus;
    lcdStatus.panelID = lcdReply.panelID;
    lcdStatus.videoStatus = lcdReply.videoStatus;

    for(int i = 0; i < lcdSetting.panelInfoList.count(); i++)
    {
        if (lcdSetting.panelInfoList.at(i).panelID == lcdReply.panelID)
        {
            if (lcdReply.videoStatus == quint32(LCD_BOARD_INPUTSTATUS_NOSIGNAL))
            {
                lcdStatus.videoStatus = LCD_INPUTSTATUS_NOSIGNAL;
            } else if (lcdReply.videoStatus == quint32(LCD_BOARD_INPUTSTATUS_DVI1))
            {
                lcdStatus.videoStatus = LCD_INPUTSTATUS_DVI1;
            } else if (lcdReply.videoStatus == quint32(LCD_BOARD_INPUTSTATUS_DVI2))
            {
                lcdStatus.videoStatus = LCD_INPUTSTATUS_DVI2;
            } else {
                lcdStatus.videoStatus = LCD_INPUTSTATUS_NOSIGNAL;
            }

            lcdStatus.blStatus = lcdReply.blStatus;
            lcdStatus.isCollect = lcdSetting.panelInfoList.at(i).isCollect;

            int j = 0;
            for(; j < m_queryVideoCmd.panelStatuList.count(); j++)
            {
                if (m_queryVideoCmd.panelStatuList.at(j).panelID == lcdReply.panelID)
                {
                    break;
                }
            }

            if (j >= m_queryVideoCmd.panelStatuList.count())
            {
                m_queryVideoCmd.panelStatuList.append(lcdStatus);
            } else {
                m_queryVideoCmd.panelStatuList.replace(j, lcdStatus);
            }
            break;
        }
    }

    if (!isCheckSLcd && !m_queryVideoCmd.timer.isActive())
    {
        emit sendVideoStatus(m_queryVideoCmd.panelStatuList, isTisSelfTest);
        m_queryVideoCmd.panelStatuList.clear();
    }
}


void SerialCtl::receBrightnessStatus(const qint8 Status)
{
    emit sendSetLcdSettingStatus(Status);
}

void SerialCtl::receBackLightStatus(const qint8 status)
{
    lcdSetting.backLightStatus = status;
    emit sendLcdSetting(lcdSetting);
}


/*******************************************
  功能：维护终端发起的操作－－设置哪些lcd屏要进行操作
        它可以只设置对哪几个屏进行亮度设置，背景灯设置等
  参数：
  返回值：
  ******************************************/
void SerialCtl::setSlcdCollectSate(const QList<PanelInfoStruct>& infoList)
{

    int collectCount = 0;
    for(int i = 0; i < infoList.count(); i++)
    {
        if (infoList.at(i).isCollect > 0)
            collectCount++;

        for(int j = 0 ; j < lcdSetting.panelInfoList.count(); j++)
        {
            if (infoList.at(i).panelID == lcdSetting.panelInfoList.at(j).panelID)
            {
                lcdSetting.panelInfoList[j].isCollect = infoList.at(i).isCollect;
                break;
            }
        }
    }
    lcdSetting.collectPanelCount = collectCount;

    configclass.setSlcdInfo(lcdSetting.panelInfoList);
    configclass.sync();
}


/*******************************************
  功能：在对lcd屏亮度设置后，如果在设定的时间内，如果收到全部lcd屏的回复，
        那么将回复的信息发送出去，如果没有，那么对没有回复的lcd屏再次发送设置亮度命令，
        如果重复次数超过设置，那么将无回复的屏设置为无应答状态，
        然后将信息发送给操作端（即发起设置亮度操作的对象）
  参数：
  返回值：
  ******************************************/
void SerialCtl::timeOutSetBirght()
{
//    qDebug() << "========== timeOutSetBirght ==============";


    if(m_brightCmd.panelStatuList.count() >= m_brightCmd.panelIDList.count() || m_brightCmd.checkCount >= CHECKLIMMIT)
    {
        //如果已经收到全部应答或者操作次数已经超过设定次数
        //无收到回复将之设置为无应答状态，然后将信息发送出去
        m_brightCmd.timer.stop();
        m_brightCmd.checkCount = 0;

        QList<LCDSTATUS> statusList;
        for(int i = 0; i < m_brightCmd.panelIDList.count(); i++)
        {
            bool isFind = false;
            LCDSTATUS lcdStatus;
            lcdStatus.enLcdStatuType = LCDSTATU_BRIGHTNESS_TYPE;

            for(int j = 0; j < m_brightCmd.panelStatuList.count();j++)
            {
                if (m_brightCmd.panelStatuList.at(j).panelID == m_brightCmd.panelIDList.at(i))
                {
                    //如果有回复,那么将videoStatus置为0x31
                    //否则将videoStatus置为0x30
                    lcdStatus.panelID = m_brightCmd.panelIDList.at(i);
                    lcdStatus.brightness = m_brightCmd.panelStatuList.at(j).brightness;
                    lcdStatus.videoStatus = LCD_ANSWER_ON;
                    statusList.append(lcdStatus);
                    isFind = true;
                    break;
                }
            }

            //末回复
            if (!isFind)
            {
                lcdStatus.panelID = m_brightCmd.panelIDList.at(i);
                lcdStatus.videoStatus = LCD_ANSWER_OFF;
                statusList.append(lcdStatus);
            }
        }
        emit lcdAnswerStatus(statusList);

        m_brightCmd.panelStatuList.clear();
        m_brightCmd.panelIDList.clear();
    } else {

        //如果末收到全部lcd屏的应答而且重复操作次数末超过设置值
        //那么查找出是哪个末应答，对它再次发送设置命令

        m_brightCmd.checkCount++;   //操作次数加１
        for(int i = 0; i < m_brightCmd.panelIDList.count(); i++)
        {
            bool isFind = false;
            for(int j = 0; j < m_brightCmd.panelStatuList.count();j++)
            {
                if (m_brightCmd.panelStatuList.at(j).panelID == m_brightCmd.panelIDList.at(i))
                {
                    isFind = true;
                    break;
                }
            }

            //末应答重新发送设置命令
            if (!isFind)
            {
                lcdSerialPotr->ctlBrightness(m_brightCmd.panelIDList.at(i), lcdSetting.brightness);
                usleep(1000 * 200);
                if (g_stDebugConfig.isDebugSerialPort)
                {
                    qDebug() << "ctlBrightness, ID:" << m_brightCmd.panelIDList.at(i);
                }
            }
        }
        //定时器重新定时
        m_brightCmd.timer.start(TIMEINTERVAL);
    }
}

/*******************************************
  功能：在对lcd屏背景灯状态设置后，如果在设定的时间内，如果收到全部lcd屏的回复，
        那么将回复的信息发送出去，如果没有，那么对没有回复的lcd屏再次发送设置命令，
        如果重复次数超过设置，那么将无回复的屏设置为无应答状态，
        然后将信息发送给操作端（即发起设置亮度操作的对象）
  参数：
  返回值：
  ******************************************/
void SerialCtl::timeOutSetBLStatu()
{
//    qDebug() << "========== timeOutSetBLStatu ==============";

    if(m_blStatuCmd.panelStatuList.count() >= m_blStatuCmd.panelIDList.count() || m_blStatuCmd.checkCount >= CHECKLIMMIT)
    {
        //如果已经收到全部应答或者操作次数已经超过设定次数
        //无收到回复将之设置为无应答状态，然后将信息发送出去
        m_blStatuCmd.timer.stop();
        m_blStatuCmd.checkCount = 0;

        QList<LCDSTATUS> statusList;
        for(int i = 0; i <  m_blStatuCmd.panelIDList.count(); i++)
        {
            LCDSTATUS lcdStatus;
            lcdStatus.enLcdStatuType = LCDSTATU_BACKLIGHT_TYPE;
            bool isFind = false;
            for(int j = 0; j < m_blStatuCmd.panelStatuList.count();j++)
            {
                if (m_blStatuCmd.panelStatuList.at(j).panelID ==  m_blStatuCmd.panelIDList.at(i))
                {
                    //如果有回复,那么将videoStatus置为0x31
                    //否则将videoStatus置为0x30
                    lcdStatus.panelID =  m_blStatuCmd.panelIDList.at(i);
                    lcdStatus.blStatus = m_blStatuCmd.panelStatuList.at(j).blStatus;
                    lcdStatus.videoStatus = LCD_ANSWER_ON;
                    statusList.append(lcdStatus);
                    isFind = true;
                    break;
                }
            }

            if (!isFind)
            {
                lcdStatus.panelID = m_blStatuCmd.panelIDList.at(i);
                lcdStatus.videoStatus = LCD_ANSWER_OFF;
                statusList.append(lcdStatus);
            }
        }
        emit lcdAnswerStatus(statusList);
        m_blStatuCmd.panelIDList.clear();
        m_blStatuCmd.panelStatuList.clear();

    } else {
        //如果末收到全部lcd屏的应答而且重复操作次数末超过设置值
        //那么查找出是哪个末应答，对它再次发送设置命令

        m_blStatuCmd.checkCount++;
        for(int i = 0; i <  m_blStatuCmd.panelIDList.count(); i++)
        {
            bool isFind = false;
            for(int j = 0; j < m_blStatuCmd.panelStatuList.count();j++)
            {
                if (m_blStatuCmd.panelStatuList.at(j).panelID ==  m_blStatuCmd.panelIDList.at(i))
                {
                    isFind = true;
                    break;
                }
            }

            if (!isFind)
            {
                lcdSerialPotr->ctlBLStatu(m_blStatuCmd.panelIDList.at(i), lcdSetting.backLightStatus);
                if (g_stDebugConfig.isDebugSerialPort)
                {
                    qDebug() << "ctlBLStatu, ID:" <<  m_blStatuCmd.panelIDList.at(i);
                }
                usleep(1000 * 200);
            }
        }
        m_blStatuCmd.timer.start(TIMEINTERVAL);
    }
}


/*******************************************
  功能：在对lcd屏状态查询设置后，如果在设定的时间内，如果收到全部lcd屏的回复，
        那么将回复的信息发送出去，如果没有，那么对没有回复的lcd屏再次发送设置命令，
        如果重复次数超过设置，那么将无回复的屏设置为无应答状态，
        然后将信息发送给操作端（即发起设置亮度操作的对象）
  参数：
  返回值：
  ******************************************/
void SerialCtl::timeOutQueryVideo()
{
//    qDebug() << "========== timeOutQueryVideo ==============";
    if(m_queryVideoCmd.panelStatuList.count() >= m_queryVideoCmd.panelIDList.count() ||
            m_queryVideoCmd.checkCount >= CHECKLIMMIT)
    {

        m_queryVideoCmd.timer.stop();
        m_queryVideoCmd.checkCount = 0;
        QList<LCDSTATUS> statusList;

        //如果已经收到全部应答或者操作次数已经超过设定次数
        //无收到回复将之设置为无应答状态，然后将信息发送出去
        for(int i = 0; i < m_queryVideoCmd.panelIDList.count(); i++)
        {
            bool isFind = false;
            LCDSTATUS lcdStatus;
            lcdStatus.enLcdStatuType = LCDSTATU_VIDEO_TYPE;

            for(int j = 0; j < m_queryVideoCmd.panelStatuList.count();j++)
            {
                if (m_queryVideoCmd.panelStatuList.at(j).panelID == m_queryVideoCmd.panelIDList.at(i))
                {
                    //如果有回复,那么将videoStatus置为0x31
                    //否则将videoStatus置为0x30
                    lcdStatus.panelID =  m_queryVideoCmd.panelIDList.at(i);
                    lcdStatus.videoStatus = m_queryVideoCmd.panelStatuList.at(j).blStatus;
                    statusList.append(lcdStatus);
                    isFind = true;
                    break;
                }
            }
            if (!isFind)
            {
                lcdStatus.panelID = m_queryVideoCmd.panelIDList.at(i);
                lcdStatus.videoStatus = LCD_INPUTSTATUS_NOSIGNAL;
                statusList.append(lcdStatus);
            }
        }

        emit sendVideoStatus(statusList, isTisSelfTest);
        isCheckSLcd = false;
        isTisSelfTest = false;

        m_queryVideoCmd.panelIDList.clear();
        m_queryVideoCmd.panelStatuList.clear();
    } else {
        //如果末收到全部lcd屏的应答而且重复操作次数末超过设置值
        //那么查找出是哪个末应答，对它再次发送设置命令

        m_queryVideoCmd.checkCount ++;
        for(int i = 0; i < m_queryVideoCmd.panelIDList.count(); i++)
        {
            bool isFind = false;
            for(int j = 0; j < m_queryVideoCmd.panelStatuList.count();j++)
            {
                if (m_queryVideoCmd.panelStatuList.at(j).panelID == m_queryVideoCmd.panelIDList.at(i))
                {
                    isFind = true;
                    break;
                }
            }

            if (!isFind)
            {
                lcdSerialPotr->queryVideoStatus(m_queryVideoCmd.panelIDList.at(i));
                if (g_stDebugConfig.isDebugSerialPort)
                {
                    qDebug() << "queryVideoStatus, ID:" << m_queryVideoCmd.panelIDList.at(i);
                }
                usleep(1000 * 200);
            }
        }
        m_queryVideoCmd.timer.start(TIMEINTERVAL);
    }
}

void SerialCtl::timeOutReSet()
{

}

/*******************************************
  功能：收到同步信息
  参数：
  返回值：
  ******************************************/
void SerialCtl::receSyncCommand(const SynchCommand& synCommand)
{
//    qDebug() << "receSyncCommand===========" << synCommand.brightness;

    int ret;
    if (m_isMaterDev <= 0)
    {
        QDateTime curDateTime = QDateTime::currentDateTime();
        QString dateTimeStr = tr("%1-%2-%3 %4:%5:%6").arg(synCommand.year + 2000).arg(synCommand.month).arg(synCommand.day)
                .arg(synCommand.hour).arg(synCommand.minute).arg(synCommand.second);

        QDateTime syncDateTime = QDateTime::fromString(dateTimeStr, "yyyy-MM-dd h:m:s");
        int second = curDateTime.secsTo(syncDateTime);

        //如果时间差超过60秒，即1分钟，那么设置从设备时间，否则不改变它
        if (second > 60 || second < -60)
        {
            //设置系统时间
            QString dateStr = QObject::tr("date -s %1/%2/%3").arg(synCommand.month).arg(synCommand.day).arg(synCommand.year+2000);
            QString timeStr = QObject::tr("date -s %1:%2:%3").arg(synCommand.hour).arg(synCommand.minute).arg(synCommand.second);
            ret = system(dateStr.toLatin1().data());
            ret = system(timeStr.toLatin1().data());
            ret = system("hwclock -w");

            if (ret < 0)
            {
                logger();
            }
        }
    }
    this->recePhotoData(synCommand.brightness);
}

void SerialCtl::initLcdBright()
{
//    qDebug() << CHECKLIMMIT << "initLcdBright=============>" << m_initCount;
    if (lcdSerialPotr->isOpen())
    {
        m_initTimer->stop();
        lcdSerialPotr->bcastCtlbrightness(lcdSetting.lvStruct[lcdSetting.defaultLv-1].lcdBirght);

        m_initCount = 0;
    } else {
        if (m_initCount <= CHECKLIMMIT)
        {
            m_initTimer->start(1 * 1000);
        } else {
            m_initTimer->stop();
            m_initCount = 0;
        }
        m_initCount = m_initCount + 1;
    }
}

void SerialCtl::updateConfig()
{
    lcdSetting.defaultLv = configclass.getLcdDefaultLV();
    lcdSetting.panelInfoList = configclass.getSLCDInfoIntList();
    lcdSetting.collectPanelCount = configclass.collectSLCDCount();

    lcdSetting.lvStruct[0] = configclass.getLv1Bright();
    lcdSetting.lvStruct[1] = configclass.getLv2Bright();
    lcdSetting.lvStruct[2] = configclass.getLv3Bright();
    lcdSetting.lvStruct[3] = configclass.getLv4Bright();

    int isCollectPS = configclass.getIsCollectPS();
    if (lcdSetting.isCollectPS != isCollectPS)
    {
        lcdSetting.isCollectPS = isCollectPS;
        if (isCollectPS <= 0)
        {
            m_initTimer->start(10);
        }
    }

}
